# 人类
import time
import utils.Logger as Logger


class Human:

    # 基本属性
    name = ""
    age = 0
    # 私有属性,私有属性在类的外部无法直接访问
    __birthday = time.localtime()

    # 类有一个名为__init__()的特殊方法（构造方法），该方法在类实例化时会自动调用，像下面这样：
    # 类定义了 __init__() 方法，类的实例化操作会自动调用 __init__() 方法。如下实例化类 MyClass，对应的 __init__() 方法就会被调用:
    # self代表的是类的实例,而非类本身
    # def __init__(self):
    #     Logger.info("Human creating")
    #     self.data = []
    #     self.name = "default name"
    #     self.age = -1
    #     print(self.__class__)
    #     Logger.info("Human created")

    # 重载后只能第二个生效?
    def __init__(self, name, age):
        Logger.info("Human creating")
        self.name = name
        self.age = age
        print(self.__class__)
        Logger.info("Human created")

    # 析构方法
    def __del__(self):
        Logger.info("Human deleting")
        Logger.info("Human deleted")

    # 比较方法
    def __cmp__(self, other):
        if self.age > other.age:
            return 1
        elif self.age < other.age:
            return -1
        else:
            return 0

    # 在类的内部，使用 def 关键字来定义一个方法，与一般函数定义不同，类方法必须包含参数 self, 且为第一个参数，self 代表的是类的实例
    def makeIdea(self, idea):
        if idea is None or idea == "":
            return "I have no idea"
        else:
            return self.name + " have an idea as below:\n" + str(idea)


# 类的单继承
class WhiteMan(Human):
    height = 180

    def __init__(self, name, age, height):
        Logger.info("Whiteman creating")
        super().__init__(name, age)
        self.height = height
        Logger.info("Whiteman created")

    def __del__(self):
        Logger.info("Whiteman deleting")
        Logger.info("Whiteman deleted")

    def makeIdea(self, idea):
        return "[WHITE] " + self.name + " have an idea as below:\n" + str(idea)


class Warrior:
    armor = "heavy armor"
    __anger = 0  # 战士使用怒气值,而非魔法

    def talent(self):
        return "Warrior talent : health recover"

    def getAnger(self):
        return self.__anger


class Mage:
    armor = "light armor"
    __mana = 50  # 法师使用魔法值

    def talent(self):
        return "Mage talent : mana recover"

    def getMana(self):
        return self.__mana


# 圣骑士继承自战士和法师
class Paladin(Warrior, Mage):
    armor = "heavy armor"
    holyPower = 100  # 圣骑士使用神圣之力
    # 方法重写 Overrider
    # def talent(self):
    #     return "Paladin talent : Invincible"


# 实例化Human和WhiteHuman
trump = WhiteMan(name="Donald Trump", age=73, height=188)
print("name=", trump.name)
print("age=", trump.age)
print("height=", trump.height)
# print("birthday", DateUtils.date2str(zhenli.birthday)) # private
print("make idea: ", trump.makeIdea("This is Trump's stupid idea"))

print("\n---------------------------------------------------\n")

xjp = Human(name="XiJinPing", age=66)
print("name=", xjp.name)
print("age=", xjp.age)
# print("birthday", DateUtils.date2str(xijinping.birthday)) # private
print("make idea: ", xjp.makeIdea("这是伟大光明正确的习思想!!!"))
print("xjp and trump compare", xjp.__cmp__(trump))
print("\n---------------------------------------------------\n")

# 多继承
Uther = Paladin()  # 乌瑟尔是圣骑士

print("乌瑟尔护甲", Uther.armor)
print("乌瑟尔愤怒-(父类私有属性)", Uther.getAnger())  # 私有属性无法被继承,如果直接使用Uther.__anger会报错
print("乌瑟尔魔法-(父类私有属性)", Uther.getMana())  # 私有属性无法被继承
print("乌瑟尔圣力", Uther.holyPower)
print("乌瑟尔天赋", Uther.talent())  # 如果没有方法冲那些,且两个父类方法名同，默认调用的是在括号中排前地父类的方法

